package com.sky.service.impl;


import com.sky.context.BaseContext;
import com.sky.mapper.AlertMapper;
import com.sky.mapper.AppealMapper;
import com.sky.mapper.ViolationRecordMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import com.sky.vo.ViolationReportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private WorkspaceService workspaceService;
    @Autowired
    private ViolationRecordMapper violationRecordMapper;
    @Autowired
    private AlertMapper alertMapper;
    @Autowired
    private AppealMapper appealMapper;

    @Override
    public void exportBusinessData(HttpServletResponse response) {
        //查询概要数据
        LocalDate  begin = LocalDate.now().minusDays(30);
        LocalDate  end = LocalDate.now();

        BusinessDataVO businessData =workspaceService.getBusinessData(LocalDateTime.of(begin,LocalTime.MIN),LocalDateTime.of(end,LocalTime.MIN));
        //写入excel
try{
    InputStream in=this.getClass().getClassLoader().getResourceAsStream("template/违法类型分布表模板.xlsx");
    XSSFWorkbook excel = new XSSFWorkbook(in);
    //获取sheet
    XSSFSheet sheet = excel.getSheet("Sheet1");
    //填充数据--时间
    sheet.getRow(1).getCell(1).setCellValue("时间:"+begin+"至"+end);
    //填充数据--车辆闯红灯
    sheet.getRow(3).getCell(2).setCellValue(businessData.getRunred());
    //填充数据--行人闯红灯
    sheet.getRow(3).getCell(4).setCellValue(businessData.getCarrunred());
    //填充数据--超速
    sheet.getRow(3).getCell(6).setCellValue(businessData.getOverspeed());
    //填充数据--总违法记录
    sheet.getRow(4).getCell(2).setCellValue(businessData.getTotalviolation());

    //填充明细数据
    for (int i = 0; i < 30; i++) {
        LocalDate date = begin.plusDays(i);
        //查询某天的违法记录
        businessData=workspaceService.getBusinessData(LocalDateTime.of(date,LocalTime.MIN),LocalDateTime.of(date,LocalTime.MAX));
        XSSFRow row=sheet.getRow(7+i);
        row.getCell(1).setCellValue(date.toString());
        row.getCell(2).setCellValue(businessData.getCarrunred());
        row.getCell(3).setCellValue(businessData.getRunred());
        row.getCell(4).setCellValue(businessData.getOverspeed());
        row.getCell(5).setCellValue(businessData.getTotalviolation());
    }
    //下载到excel
    ServletOutputStream out = response.getOutputStream();
    excel.write(out);
    //关闭资源
    excel.close();
    out.close();
} catch (IOException e) {
    throw new RuntimeException(e);
}

    }

    /**
     * 违法记录饼图
     * @param begin
     * @param end
     * @return
     */
    @Override
    public ViolationReportVO getViolationPie(LocalDate begin, LocalDate end) {
        //存放begin-end之间的每天日期
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        //超速
        Double overSpeedList= 0.0;
        //闯红灯
        Double carRunRedList= 0.0;
        //行人闯红灯
        Double runRedList= 0.0;
        //压线
        Double touchLineList= 0.0;
        //变道
        Double turnWrongList= 0.0;
        //总违法记录
        Double violationList = 0.0;
        for (LocalDate date : dateList) {
            //获取日期对应的违法记录数
            LocalDateTime beginTime =LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map  = new HashMap();
            map.put("begin", beginTime);
            map.put("end", endTime);
            overSpeedList+=violationRecordMapper.totalOverSpeed(map);
            carRunRedList+=violationRecordMapper.totalTurnWrong(map);
            runRedList+=violationRecordMapper.totalTouchLine(map);
            touchLineList+=violationRecordMapper.totalCarRunRed(map);
            turnWrongList+=violationRecordMapper.totalRunRed(map);

        }
        violationList+=overSpeedList+carRunRedList+runRedList+touchLineList+turnWrongList;
        //组装返回结果
        return ViolationReportVO.builder().
                overSpeedList(StringUtils.join(overSpeedList, ","))
                .turnWrongList(StringUtils.join(turnWrongList, ","))
                .carRunRedList(StringUtils.join(carRunRedList, ","))
                .touchLineList(StringUtils.join(touchLineList, ","))
                .runRedList(StringUtils.join(runRedList, ","))
                .violationList(StringUtils.join(violationList, ","))
                .build();
    }

    @Override
    public ViolationReportVO getmyViolationStatistics() {
        Double total=violationRecordMapper.getMytotal(BaseContext.getCurrentId());
        return ViolationReportVO.builder().
                totalViolation(StringUtils.join(total))
                .build();
    }

    @Override
    public ViolationReportVO getWaitingAppeal() {
        Double total=appealMapper.getMyWaitingAppeal(BaseContext.getCurrentId());
        return ViolationReportVO.builder().
                waitWarning(StringUtils.join(total))
                .build();
    }

    /**
     * 违法记录统计与折线图
     * @param begin
     * @param end
     * @return
     */
    @Override
    public ViolationReportVO getViolationStatistics(LocalDate begin, LocalDate end) {
        //存放begin-end之间的每天日期
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)) {
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        //超速
        List<Double> overSpeedList= new ArrayList<>();
        //闯红灯
        List<Double> carRunRedList= new ArrayList<>();
        //行人闯红灯
        List<Double> runRedList= new ArrayList<>();
        //压线
        List<Double> touchLineList= new ArrayList<>();
        //变道
        List<Double> turnWrongList= new ArrayList<>();
        //每天总违法记录
        List<Double> violationList = new ArrayList<>();
        //总违法记录
        Double totalViolation = 0.0;
        //待处理预警
        Double waitWarning = 0.0;

        for (LocalDate date : dateList) {
            //获取日期对应的违法记录数
            LocalDateTime beginTime =LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map  = new HashMap();
            map.put("begin", beginTime);
            map.put("end", endTime);
            //List<Double> violation = violationRecordMapper.pieMap(map);
            Double violation1=violationRecordMapper.totalOverSpeed(map);
            Double violation2=violationRecordMapper.totalTurnWrong(map);
            Double violation3=violationRecordMapper.totalTouchLine(map);
            Double violation4=violationRecordMapper.totalCarRunRed(map);
            Double violation5=violationRecordMapper.totalRunRed(map);
            Double violation = violationRecordMapper.totalByMap(map);
            Double execution = alertMapper.countByMap(map);

            violationList.add(violation == null ? 0.0 :violation);
            overSpeedList.add(violation1== null ? 0.0 :violation1 );
            carRunRedList.add(violation4 == null ? 0.0 : violation4);
            runRedList.add(violation5 == null ? 0.0 : violation5);
            touchLineList.add(violation3 == null ? 0.0 : violation3);
            turnWrongList.add(violation2 == null ? 0.0 : violation2);
            totalViolation+=violationList.get(dateList.indexOf(date));
            waitWarning +=execution;
        }
        //组装返回结果
        return ViolationReportVO.builder().
                dateList(StringUtils.join(dateList, ","))
                .violationList(StringUtils.join(violationList, ","))
                .overSpeedList(StringUtils.join(overSpeedList, ","))
                .turnWrongList(StringUtils.join(turnWrongList, ","))
                .carRunRedList(StringUtils.join(carRunRedList, ","))
                .touchLineList(StringUtils.join(touchLineList, ","))
                .totalViolation(StringUtils.join(totalViolation))
                .runRedList(StringUtils.join(runRedList, ","))
                .waitWarning(StringUtils.join(waitWarning))
                .build();
    }
}
